const path = require('path')
const _ = require('lodash')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const { merge } = require('webpack-merge')
const common = require('./webpack.common')
const config = require('./config')

const plugins = [
  new webpack.DefinePlugin({
    BASE_URL: JSON.stringify(`/${config.prod.assets}/`),
  }),
  new HtmlWebpackPlugin({
    template: path.resolve(__dirname, `${config.prod.assets}/index.html`),
    title: 'hello vue',
    filename: path.resolve(__dirname, `${config.prod.dist}/index.html`),
  }),
  new CopyWebpackPlugin({
    patterns: [
      {
        from: path.resolve(__dirname, `${config.prod.assets}`),
        to: path.resolve(
          __dirname,
          `${config.prod.dist}/${config.prod.assets}`,
        ),
        globOptions: {
          ignore: ['*.html'],
        },
      },
    ],
  }),
  new CleanWebpackPlugin(),
  new MiniCssExtractPlugin(),
  new OptimizeCssAssetsWebpackPlugin(),
]

module.exports = merge(common, {
  mode: 'production',
  output: {
    path: path.resolve(__dirname, config.prod.dist),
    filename: '[name]_[contenthash:8].js',
    publicPath: config.prod.publicPath || '/',
  },
  devtool: 'none',
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },
      {
        test: /\.less$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'],
      },
    ],
  },
  plugins: config.prod.analysis
    ? _.concat(plugins, new BundleAnalyzerPlugin())
    : plugins,
  optimization: {
    splitChunks: config.prod.splitChunks || {
      chunks: 'all',
      maxInitialRequests: 5,
      cacheGroups: {
        dll: {
          name: 'dll',
          minChunks: 1,
          test: (module) => {
            return (
              module.resource &&
              module.resource.endsWith('.js') &&
              module.resource.includes('vue')
            )
          },
          priority: 5,
        },
        vendor: {
          name: 'vendors',
          minChunks: 1,
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
        },
        common: {
          name: 'common',
          minChunks: 2,
          minSize: 0,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
    runtimeChunk: {
      name: 'manifest',
    },
  },
})
